package com.bds.snatch.system.queue;

import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.impl.NutDao;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.bds.snatch.model.H2Urls;
import com.bds.snatch.model.Task;
import com.bds.snatch.model.Template;
import com.bds.snatch.model.TemplateUrl;
import com.bds.snatch.model.Tresult;
import com.bds.snatch.system.service.BalanceService;
import com.bds.snatch.system.service.MessageService;
import com.bds.snatch.system.service.ParseService;
import com.bds.snatch.system.util.Const;
import com.bds.snatch.system.util.PhantomjsUtilV2;
import com.bds.snatch.system.util.SpringContextHolder;
import com.bds.snatch.system.util.UploadOSSUtil;

@Service
public class SnatchConsumer extends Thread {
	private static final Logger logger = Logger.getLogger(SnatchConsumer.class);
	private Dao h2dao;

	public void doStart(Dao h2dao) {
		this.h2dao = h2dao;
		this.start();
	}

	@Override
	public void run() {
		consume();

	}

	public void consume() {
		NutDao apiDao = SpringContextHolder.getBean("dao");
		ParseService parseService = SpringContextHolder.getBean("parseService");
		BalanceService balanceService = SpringContextHolder.getBean("balanceService");

		MessageService messageService = SpringContextHolder.getBean("messageService");
		logger.info("****PortalConsumer启动消息*****");
		while (true) {
			try {
				H2Urls info = TQueue.getQueue().take();
				logger.info("****接收到消息:" + info.getUrl() + ",队列剩余" + TQueue.getQueue().size() + "*****");
				if (info.getType().equals("url")) {
					apiDao.update(TemplateUrl.class, Chain.make("status", 1), Cnd.where("id", "=", info.getId()));
				} else if (info.getType().equals("portal")) {
					apiDao.update(Task.class, Chain.make("status", 1), Cnd.where("id", "=", info.getId()));
				}

				String url = info.getUrl();
				String requestId = info.getRequest_id();
				// String isjs = info.getIsjs();

				try {

					// webdriver指针指定获取哪一个webdriver
					WebDriver driver = PhantomjsUtilV2.getDriver();

					if (url.startsWith("http")) {
						driver.get(url);
					} else {
						url = "http://" + url;
						driver.get(url);
					}

					java.net.URL netUrl = new java.net.URL(url);
					JavascriptExecutor js = (JavascriptExecutor) driver;
					// 获取网页高度，用于滚动到底部，防止仅加载一部分数据
					Long height = (Long) js.executeScript("return document.body.scrollHeight");

					logger.info("##########" + url + "高度:" + height + "##########");
					Dimension POPULAR_DISPLAY_SIZE = new Dimension(3000, height.intValue());
					driver.manage().window().setSize(POPULAR_DISPLAY_SIZE);
					try {
						js.executeScript("scrollTo(0,30000)");
					} catch (Exception E) {

					}
					TimeUnit.SECONDS.sleep(10);
					
					String html = driver.getPageSource();
					logger.info("##########获取网页源码" + requestId + "##########");
					Document doc = Jsoup.parse(html);

					
					if (StringUtils.isEmpty(doc.baseUri())) {
						String rurl = netUrl.getHost();
						doc.head().prependElement("base").attr("href", "http://" + rurl);

					}
					// doc.head()
					// .append("<script
					// type='text/javascript'>window.onerror=function(){return
					// true;}</script>");
					// 添加js和css
					// doc.setBaseUri(Const.PORTAL_HOST);
					// doc.select("base").attr("href", Const.PORTAL_HOST);
					doc.head().appendElement("link")
							.attr("href", Const.PORTAL_HOST + "/web/res/css/thinkdata-style.css")
							.attr("rel", "stylesheet");

					doc.head().appendElement("link").attr("href", Const.PORTAL_HOST + "/web/res/css/smartMenu.css")
							.attr("rel", "stylesheet");
					// doc.head().appendElement("script").attr("src",
					// Const.PORTAL_HOST + "/web/res/js/jquery-1.10.2.min.js");
					// doc.head().appendElement("script").attr("src",
					// Const.PORTAL_HOST + "/web/res/js/jquery-smartMenu.js");

					doc.body().appendElement("script").attr("src",
							Const.PORTAL_HOST + "/web/res/js/jquery-1.10.2.min.js");
					doc.body().appendElement("script").attr("src", Const.PORTAL_HOST + "/web/res/js/fetch-element.js");

					doc.body().appendElement("script").attr("src",
							Const.PORTAL_HOST + "/web/res/js/layer-v3.0.3/layer/layer.js");

					doc.body().appendElement("script").attr("src",
							Const.PORTAL_HOST + "/web/res/js/jquery-smartMenu.js");
					doc.body().appendElement("script").attr("src",
							Const.PORTAL_HOST + "/web/res/js/jquery.ellocate.js");
					Elements elements = doc.getAllElements();
					for (int i = 0; i < elements.size(); i++) {
						Element e = elements.get(i);
						// 每个元素都加上__thinkdata_id属性
						e.attributes().put(Const.THINKDATA_ID, i + "");
						// 进入redis时不用去除a标签的href，返回前端时去除即可
						// <script type="text/javascript" async=""
						// src="//cpro.baidustatic.com/cpro/ui/pr.js"></script>
						// 对非a标签的href属性添加协议类型

						if (e.attributes().hasKey("href") && e.attr("href").startsWith("//")) {
							e.attr("href", "http:" + e.attr("href"));
						} else if (e.attributes().hasKey("src") && e.attr("src").startsWith("//")) {
							e.attr("src", "http:" + e.attr("src"));
						}
					}

					// apiDao.update(Task.class, Chain.make("charset", charset),
					// Cnd.where("request_id", "=", requestId));

					if (info.getId() != null) {
						apiDao.clear(Tresult.class, Cnd.where("url_id", "=", info.getId()));
					}

					if (info.getType().equals("portal")) {//拼装模板，显示页面
						String docHtml = doc.html();
						UploadOSSUtil.uploadHtmlFile(requestId, docHtml.getBytes("utf-8"));
						logger.info("##########上传OSS网页源码完成" + requestId + "##########");
						apiDao.update(Task.class, Chain.make("status", 2), Cnd.where("id", "=", info.getId()));
					}
				} catch (Exception e) {
					if (info.getType().equals("portal")) {

						apiDao.update(Task.class, Chain.make("status", 3), Cnd.where("id", "=", info.getId()));
					}
					logger.error("获取网页源码异常:url:" + url, e);
				}

				logger.info("****消费完一条:" + info.getUrl() + ",队列剩余" + TQueue.getQueue().size() + "****");
			} catch (Exception e) {
				logger.error("", e);

			}
		}

	}
}
